﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace Assist
{
	public class LinkCurve
	{
		public LinkCurve()
		{
		}

		public LinkCurve(List<Curve> curveList)
		{
			this.CurveList = curveList;
		}

		public void Add(Curve curve)
		{
			this.CurveList.Add(curve);
		}

		public double Length
		{
			get
			{
				double num = 0.0;
				foreach (Curve curve in this.CurveList)
				{
					num += curve.Length;
				}
				return num;
			}
		}

		public int Count
		{
			get
			{
				return this.CurveList.Count;
			}
		}

		public List<XYZ> Tessellate
		{
			get
			{
				List<XYZ> list = new List<XYZ>();
				foreach (Curve curve in this.CurveList)
				{
					list.AddRange(curve.Tessellate());
				}
				return list;
			}
		}

		private double formatAngle(double angle)
		{
			int num = (int)(angle / Math.PI*2);
			double num2 = angle - (double)num * Math.PI*2;
			if (num2 < 0.0)
			{
				num2 += Math.PI*2;
			}
			return num2;
		}

		private double GetAngle(XYZ ptOut)
		{
			XYZ xyz = ptOut - XYZ.Zero;
			double angle = XYZ.BasisX.AngleOnPlaneTo(xyz, XYZ.BasisZ);
			return this.formatAngle(angle);
		}

		public List<IntersectionPoint> Divide(double num, UIApplication uiApp)
		{
			double num2 = this.Length / num;
			this.Sort(uiApp);
			List<IntersectionPoint> list = new List<IntersectionPoint>();
			double num3 = 0.0;
			foreach (Curve curve in this.CurveList)
			{
				bool flag = true;
				if (curve.IsBound)
				{
					XYZ xyz = curve.GetEndPoint(0);
					while (flag)
					{
						if (curve is Line)
						{
							Transform transform = curve.ComputeDerivatives(1.0, true);
							XYZ ptOut = transform.get_Basis(0);
							double angle = this.GetAngle(ptOut);
							Arc arc = uiApp.ActiveUIDocument.Document.CreatYJKArc(xyz, Math.Abs(num2 - num3), angle - 1.0, angle + 1.0, XYZ.BasisX, XYZ.BasisY);
							IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
							curve.Intersect(arc, out intersectionResultArray);
							if (intersectionResultArray != null)
							{
								IEnumerator enumerator2 = intersectionResultArray.GetEnumerator();
								{
									if (enumerator2.MoveNext())
									{
										IntersectionResult intersectionResult = (IntersectionResult)enumerator2.Current;
										xyz = intersectionResult.XYZPoint;
										list.Add(new IntersectionPoint(xyz, this.GetAngle(ptOut)));
										num3 = 0.0;
									}
									continue;
								}
							}
							flag = false;
							try
							{
								num3 += uiApp.Application.CreatYJKLine(xyz, curve.GetEndPoint(1), true).Length;
								continue;
							}
							catch
							{
								continue;
							}
						}
						if (!(curve is Arc))
						{
							curve.GetYJKEndParameter(0);
							curve.GetYJKEndParameter(1);
							IList<XYZ> list2 = curve.Tessellate();
							double num4 = 0.0;
							double num5 = 0.0;
							XYZ xyz2 = curve.GetEndPoint(0);
							foreach (XYZ xyz3 in list2)
							{
								try
								{
									num4 += xyz2.DistanceTo(xyz3);
									num5 += xyz2.DistanceTo(xyz3);
									if (num4 >= num2 - num3)
									{
										XYZ ptOut2 = xyz3 - xyz2;
										list.Add(new IntersectionPoint(xyz3, this.GetAngle(ptOut2)));
										num4 = 0.0;
										num3 = 0.0;
									}
									xyz2 = xyz3;
								}
								catch (Exception ex)
								{
									MessageBox.Show(ex.Message);
								}
							}
							if (list.Count > 0)
							{
								IntersectionPoint intersectionPoint = list[list.Count - 1];
								bool flag2 = false;
								IEnumerator<XYZ> enumerator4 = list2.GetEnumerator();
								{
									while (enumerator4.MoveNext())
									{
										XYZ xyz4 = enumerator4.Current;
										if (xyz4.IsAlmostEqualTo(intersectionPoint.Point))
										{
											flag2 = true;
										}
										if (flag2)
										{
											num3 += xyz2.DistanceTo(xyz4);
										}
										xyz2 = xyz4;
									}
									goto IL_3AF;
								}
								goto IL_3A6;
							}
							goto IL_3A6;
							IL_3AF:
							flag = false;
							continue;
							IL_3A6:
							num3 += curve.Length;
							goto IL_3AF;
						}
						double hyendParameter = curve.GetYJKEndParameter(0);
						double hyendParameter2 = curve.GetYJKEndParameter(1);
						double num6 = hyendParameter;
						while (flag)
						{
							double num7 = num6 + (hyendParameter2 - hyendParameter) * (num2 - num3) / curve.Length;
							if (curve.IsInside(num7))
							{
								double num8 = curve.ComputeNormalizedParameter(num7);
								XYZ pt = curve.Evaluate(num8, true);
								Transform transform2 = curve.ComputeDerivatives(num7, false);
								XYZ ptOut3 = transform2.get_Basis(0);
								list.Add(new IntersectionPoint(pt, this.GetAngle(ptOut3)));
								double num9 = curve.Length * (hyendParameter2 - num7) / (hyendParameter2 - hyendParameter);
								if (num9 < num2)
								{
									flag = false;
									num3 = curve.Length * (hyendParameter2 - num7) / (hyendParameter2 - hyendParameter);
								}
								else
								{
									num6 = num7;
									num3 = 0.0;
								}
							}
							else
							{
								flag = false;
								num3 = curve.Length * (hyendParameter2 - num7) / (hyendParameter2 - hyendParameter);
							}
						}
					}
				}
				else
				{
					if (!(curve is Arc))
					{
						curve.GetYJKEndParameter(0);
						curve.GetYJKEndParameter(1);
						IList<XYZ> list3 = curve.Tessellate();
						double num10 = 0.0;
						double num11 = 0.0;
						XYZ xyz5 = curve.GetEndPoint(0);
						foreach (XYZ xyz6 in list3)
						{
							try
							{
								num10 += xyz5.DistanceTo(xyz6);
								num11 += xyz5.DistanceTo(xyz6);
								if (num10 >= num2 - num3)
								{
									XYZ ptOut4 = xyz6 - xyz5;
									list.Add(new IntersectionPoint(xyz6, this.GetAngle(ptOut4)));
									num10 = 0.0;
									num3 = 0.0;
								}
								xyz5 = xyz6;
							}
							catch (Exception ex2)
							{
								MessageBox.Show(ex2.Message);
							}
						}
						if (list.Count > 0)
						{
							IntersectionPoint intersectionPoint2 = list[list.Count - 1];
							bool flag3 = false;
							IEnumerator<XYZ> enumerator6 = list3.GetEnumerator();
							{
								while (enumerator6.MoveNext())
								{
									XYZ xyz7 = enumerator6.Current;
									if (xyz7.IsAlmostEqualTo(intersectionPoint2.Point))
									{
										flag3 = true;
									}
									if (flag3)
									{
										num3 += xyz5.DistanceTo(xyz7);
									}
									xyz5 = xyz7;
								}
								goto IL_5F6;
							}
							goto IL_5ED;
						}
						goto IL_5ED;
						IL_5F6:
						flag = false;
						continue;
						IL_5ED:
						num3 += curve.Length;
						goto IL_5F6;
					}
					double hyendParameter3 = curve.GetYJKEndParameter(0);
					double hyendParameter4 = curve.GetYJKEndParameter(1);
					double num12 = hyendParameter3;
					while (flag)
					{
						double num13 = num12 + (hyendParameter4 - hyendParameter3) * (num2 - num3) / curve.Length;
						if (curve.IsInside(num13))
						{
							double num14 = curve.ComputeNormalizedParameter(num13);
							XYZ pt2 = curve.Evaluate(num14, true);
							Transform transform3 = curve.ComputeDerivatives(num13, false);
							XYZ ptOut5 = transform3.get_Basis(0);
							list.Add(new IntersectionPoint(pt2, this.GetAngle(ptOut5)));
							double num15 = curve.Length * (hyendParameter4 - num13) / (hyendParameter4 - hyendParameter3);
							if (num15 < num2)
							{
								flag = false;
								num3 = curve.Length * (hyendParameter4 - num13) / (hyendParameter4 - hyendParameter3);
							}
							else
							{
								num12 = num13;
								num3 = 0.0;
							}
						}
						else
						{
							flag = false;
							num3 = curve.Length * (hyendParameter4 - num13) / (hyendParameter4 - hyendParameter3);
						}
					}
				}
			}
			if ((double)list.Count > num - 1.0)
			{
				IntersectionPoint item = list[list.Count - 1];
				list.Remove(item);
			}
			return list;
		}

		public List<IntersectionPoint> Liner(double length, UIApplication uiApp)
		{
			double num = Math.Ceiling(this.Length / length);
			this.Sort(uiApp);
			List<IntersectionPoint> list = new List<IntersectionPoint>();
			double num2 = 0.0;
			foreach (Curve curve in this.CurveList)
			{
				bool flag = true;
				if (curve.IsBound)
				{
					XYZ xyz = curve.GetEndPoint(0);
					while (flag)
					{
						if (curve is Line)
						{
							Transform transform = curve.ComputeDerivatives(1.0, true);
							XYZ ptOut = transform.get_Basis(0);
							double angle = this.GetAngle(ptOut);
							Arc arc = uiApp.ActiveUIDocument.Document.CreatYJKArc(xyz, Math.Abs(length - num2), angle - 1.0, angle + 1.0, XYZ.BasisX, XYZ.BasisY);
							IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
							curve.Intersect(arc, out intersectionResultArray);
							if (intersectionResultArray != null)
							{
								IEnumerator enumerator2 = intersectionResultArray.GetEnumerator();
								{
									if (enumerator2.MoveNext())
									{
										IntersectionResult intersectionResult = (IntersectionResult)enumerator2.Current;
										xyz = intersectionResult.XYZPoint;
										list.Add(new IntersectionPoint(xyz, this.GetAngle(ptOut)));
										num2 = 0.0;
									}
									continue;
								}
							}
							flag = false;
							try
							{
								num2 += uiApp.Application.CreatYJKLine(xyz, curve.GetEndPoint(1), true).Length;
								continue;
							}
							catch
							{
								continue;
							}
						}
						if (!(curve is Arc))
						{
							curve.GetYJKEndParameter(0);
							curve.GetYJKEndParameter(1);
							IList<XYZ> list2 = curve.Tessellate();
							double num3 = 0.0;
							double num4 = 0.0;
							XYZ xyz2 = curve.GetEndPoint(0);
							foreach (XYZ xyz3 in list2)
							{
								try
								{
									num3 += xyz2.DistanceTo(xyz3);
									num4 += xyz2.DistanceTo(xyz3);
									if (num3 >= length - num2)
									{
										XYZ ptOut2 = xyz3 - xyz2;
										list.Add(new IntersectionPoint(xyz3, this.GetAngle(ptOut2)));
										num3 = 0.0;
										num2 = 0.0;
									}
									xyz2 = xyz3;
								}
								catch (Exception ex)
								{
									MessageBox.Show(ex.Message);
								}
							}
							if (list.Count > 0)
							{
								IntersectionPoint intersectionPoint = list[list.Count - 1];
								bool flag2 = false;
								IEnumerator<XYZ> enumerator4 = list2.GetEnumerator();
								{
									while (enumerator4.MoveNext())
									{
										XYZ xyz4 = enumerator4.Current;
										if (xyz4.IsAlmostEqualTo(intersectionPoint.Point))
										{
											flag2 = true;
										}
										if (flag2)
										{
											num2 += xyz2.DistanceTo(xyz4);
										}
										xyz2 = xyz4;
									}
									goto IL_3B4;
								}
								goto IL_3AB;
							}
							goto IL_3AB;
							IL_3B4:
							flag = false;
							continue;
							IL_3AB:
							num2 += curve.Length;
							goto IL_3B4;
						}
						double hyendParameter = curve.GetYJKEndParameter(0);
						double hyendParameter2 = curve.GetYJKEndParameter(1);
						double num5 = hyendParameter;
						while (flag)
						{
							double num6 = num5 + (hyendParameter2 - hyendParameter) * (length - num2) / curve.Length;
							if (curve.IsInside(num6))
							{
								double num7 = curve.ComputeNormalizedParameter(num6);
								XYZ pt = curve.Evaluate(num7, true);
								Transform transform2 = curve.ComputeDerivatives(num6, false);
								XYZ ptOut3 = transform2.get_Basis(0);
								list.Add(new IntersectionPoint(pt, this.GetAngle(ptOut3)));
								double num8 = curve.Length * (hyendParameter2 - num6) / (hyendParameter2 - hyendParameter);
								if (num8 < length)
								{
									flag = false;
									num2 = curve.Length * (hyendParameter2 - num6) / (hyendParameter2 - hyendParameter);
								}
								else
								{
									num5 = num6;
									num2 = 0.0;
								}
							}
							else
							{
								flag = false;
								num2 = curve.Length * (hyendParameter2 - num6) / (hyendParameter2 - hyendParameter);
							}
						}
					}
				}
				else
				{
					if (!(curve is Arc))
					{
						curve.GetYJKEndParameter(0);
						curve.GetYJKEndParameter(1);
						IList<XYZ> list3 = curve.Tessellate();
						double num9 = 0.0;
						double num10 = 0.0;
						XYZ xyz5 = curve.GetEndPoint(0);
						foreach (XYZ xyz6 in list3)
						{
							try
							{
								num9 += xyz5.DistanceTo(xyz6);
								num10 += xyz5.DistanceTo(xyz6);
								if (num9 >= length - num2)
								{
									XYZ ptOut4 = xyz6 - xyz5;
									list.Add(new IntersectionPoint(xyz6, this.GetAngle(ptOut4)));
									num9 = 0.0;
									num2 = 0.0;
								}
								xyz5 = xyz6;
							}
							catch (Exception ex2)
							{
								MessageBox.Show(ex2.Message);
							}
						}
						if (list.Count > 0)
						{
							IntersectionPoint intersectionPoint2 = list[list.Count - 1];
							bool flag3 = false;
							IEnumerator<XYZ> enumerator6 = list3.GetEnumerator();
							{
								while (enumerator6.MoveNext())
								{
									XYZ xyz7 = enumerator6.Current;
									if (xyz7.IsAlmostEqualTo(intersectionPoint2.Point))
									{
										flag3 = true;
									}
									if (flag3)
									{
										num2 += xyz5.DistanceTo(xyz7);
									}
									xyz5 = xyz7;
								}
								goto IL_5FB;
							}
							goto IL_5F2;
						}
						goto IL_5F2;
						IL_5FB:
						flag = false;
						continue;
						IL_5F2:
						num2 += curve.Length;
						goto IL_5FB;
					}
					double hyendParameter3 = curve.GetYJKEndParameter(0);
					double hyendParameter4 = curve.GetYJKEndParameter(1);
					double num11 = hyendParameter3;
					while (flag)
					{
						double num12 = num11 + (hyendParameter4 - hyendParameter3) * (length - num2) / curve.Length;
						if (curve.IsInside(num12))
						{
							double num13 = curve.ComputeNormalizedParameter(num12);
							XYZ pt2 = curve.Evaluate(num13, true);
							Transform transform3 = curve.ComputeDerivatives(num12, false);
							XYZ ptOut5 = transform3.get_Basis(0);
							list.Add(new IntersectionPoint(pt2, this.GetAngle(ptOut5)));
							double num14 = curve.Length * (hyendParameter4 - num12) / (hyendParameter4 - hyendParameter3);
							if (num14 < length)
							{
								flag = false;
								num2 = curve.Length * (hyendParameter4 - num12) / (hyendParameter4 - hyendParameter3);
							}
							else
							{
								num11 = num12;
								num2 = 0.0;
							}
						}
						else
						{
							flag = false;
							num2 = curve.Length * (hyendParameter4 - num12) / (hyendParameter4 - hyendParameter3);
						}
					}
				}
			}
			if ((double)list.Count > num - 1.0)
			{
				IntersectionPoint item = list[list.Count - 1];
				list.Remove(item);
			}
			return list;
		}

		private double BetweenTheAngles(double dSAngle, double dEAngle, bool range2PI)
		{
			dSAngle = this.formatAngle(dSAngle);
			dEAngle = this.formatAngle(dEAngle);
			if (Math.Abs(dEAngle - dSAngle) < 1E-05)
			{
				return 0.0;
			}
			if (range2PI && dEAngle < dSAngle)
			{
				dEAngle += Math.PI*2;
			}
			return dEAngle - dSAngle;
		}

		public bool IsContains(UIApplication uiApp, Curve curve)
		{
			foreach (Curve c in this.CurveList)
			{
				if (CurveAssistFunc.GetOverlapType(uiApp, curve, c) == OverlapType.eOverlap)
				{
					return true;
				}
			}
			return false;
		}

		private Curve GetReverseCurve(Curve cur, UIApplication uiApp)
		{
			Curve result;
			if (cur is Line)
			{
				XYZ hyendPoint = cur.GetEndPoint(0);
				XYZ hyendPoint2 = cur.GetEndPoint(1);
				result = uiApp.Application.CreatYJKLine(hyendPoint2, hyendPoint, true);
			}
			else if (cur is Arc)
			{
				Arc arc = cur as Arc;
				XYZ hyendPoint3 = cur.GetEndPoint(0);
				XYZ hyendPoint4 = cur.GetEndPoint(1);
				XYZ radianPnt = arc.Tessellate()[1];
				XYZ center = arc.Center;
				result = uiApp.Application.CreatYJKArc(hyendPoint4, hyendPoint3, radianPnt);
			}
			else
			{
				result = cur;
			}
			return result;
		}

		public void Sort(UIApplication uiApp)
		{
			if (this.CurveList.Count > 1)
			{
				List<XYZ> list = new List<XYZ>();
				List<Curve> list2 = new List<Curve>();
				foreach (Curve curve in this.CurveList)
				{
					list.Clear();
					foreach (Curve curve2 in this.CurveList)
					{
						if (CurveAssistFunc.GetOverlapType(uiApp, curve, curve2) != OverlapType.eOverlap)
						{
							IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
							curve.Intersect(curve2, out intersectionResultArray);
							if (intersectionResultArray != null && intersectionResultArray.Size == 1)
							{
                                list.Add(intersectionResultArray.get_Item(0).XYZPoint);
							}
						}
					}
					if (list.Count == 1 && list[0].IsAlmostEqualTo(curve.GetEndPoint(1)))
					{
						list2.Add(curve);
						break;
					}
				}
				if (list2.Count <= 0)
				{
					list2.Add(this.CurveList[0]);
				}
				while (list2.Count < this.CurveList.Count)
				{
					Curve curve3 = list2[list2.Count - 1];
					foreach (Curve curve4 in this.CurveList)
					{
						if (CurveAssistFunc.GetOverlapType(uiApp, curve3, curve4) != OverlapType.eOverlap)
						{
							IntersectionResultArray intersectionResultArray2 = new IntersectionResultArray();
							curve3.Intersect(curve4, out intersectionResultArray2);
                            if (intersectionResultArray2 != null && intersectionResultArray2.Size > 0 && intersectionResultArray2.get_Item(0).XYZPoint.IsAlmostEqualTo(curve3.GetEndPoint(1)))
							{
                                if (intersectionResultArray2.get_Item(0).XYZPoint.IsAlmostEqualTo(curve4.GetEndPoint(0)))
								{
									list2.Add(curve4);
								}
								else
								{
									list2.Add(this.GetReverseCurve(curve4, uiApp));
								}
							}
						}
					}
				}
				this.CurveList = list2;
				return;
			}
			try
			{
				this.CurveList[0].GetEndPoint(0);
			}
			catch
			{
				MessageBox.Show("目前不能在闭合环中阵列，请重新选择。");
			}
		}

		public List<Curve> CurveList = new List<Curve>();
	}
}
